package com.ding.easycontroller;

import com.ding.easycontroller.bean.ConsoleWork;
import com.ding.easycontroller.filter.HandlerFilter;
import com.ding.easycontroller.service.*;
import com.ding.easycontroller.utils.ClassLoadUtils;
import com.ding.easycontroller.utils.ConsoleUtils;
import com.ding.easycontroller.utils.RequestUtils;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

import javax.script.ScriptEngine;
import javax.script.ScriptException;

@SpringBootApplication
public class EasyControllerApplication {

    public static void main(String[] args) throws ScriptException {

        ConfigurableApplicationContext context = SpringApplication.run(EasyControllerApplication.class, args);

        ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();

        ClassLoadUtils.setParrentClassLoader(contextClassLoader);

        ConsoleWork consoleWork = context.getBean(ConsoleWork.class);

        ConsoleUtils.setConsole(consoleWork);

        HandlerFilter handlerFilter = context.getBean(HandlerFilter.class);
        RequestUtils.setHandlerFilter(handlerFilter);

        //初始化脚本引擎
        ScriptEngine engine = context.getBean(ScriptEngine.class);
        initScriptEngine(engine);

        //初始化插件
        PluginService pluginService = context.getBean(PluginService.class);
        pluginService.init();

        //初始化filter
        FilterService filterService = context.getBean(FilterService.class);
        filterService.init();

        //初始化dao
        DaoService daoService = context.getBean(DaoService.class);
        daoService.init();

        //初始化service
        ServiceService serviceService = context.getBean(ServiceService.class);
        serviceService.init();

        //初始化controller
        ControllerService controllerService = context.getBean(ControllerService.class);
        controllerService.init();

        //初始化controller
        WebSocketService webSocketService = context.getBean(WebSocketService.class);
        webSocketService.init();


    }

    private static void initScriptEngine(ScriptEngine engine) {

        try {

            //添加控制台
            engine.eval("var console = Java.type('com.ding.easycontroller.utils.ConsoleUtils');");

            //所有对js可用的插件一律通过plugins对象进行调用
            engine.eval("var plugins={}");
            engine.eval("var services={}");
            engine.eval("var daos={}");

            //添加功能单元
            engine.eval("var utils={}");
            engine.eval("utils.response=Java.type('com.ding.easycontroller.utils.ResponseUtils');");
            engine.eval("utils.request=Java.type('com.ding.easycontroller.utils.RequestUtils');");
            request(engine);

            //将象转换为字符串
            engine.eval("function __objToString(obj){\n " +
                    "if(typeof obj ==='string'){return obj}\n" +
                    "if(typeof obj ==='function'){return obj.toString()}\n" +
                    "return JSON.stringify(obj)}");


            //创建一个空的obj
            engine.eval("function __createJson(){return {};}");
            engine.eval("function __createArray(){return [];}");

            //清空临时对象防止误用
            engine.eval("Java=undefined");

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private static void request(ScriptEngine engine) {
        try {

            //默认的请求头
            engine.eval("__defaultRequestHeads={'Content-Type':'application/json;charset=UTF-8'}");

            //自动判断第二,第三个参数并进行请求
            /*
                如果第二个参数为字符串,那么第二个参数就是请求体,请求将会自动使用_defaultRequestHeads作为请求参数进行请求,第三个参数被忽略

                如果第二个参数是一个map,那么第二个参数就是请求头

             */
            engine.eval("function go(req){return utils.request.go(req);}");

            engine.eval(" function _go(url, method, config) {\n" +
                    "        if (typeof url !== 'string') {\n" +
                    "            return null;\n" +
                    "        }\n" +
                    "        if (!config) {\n" +
                    "            config = {heads: __defaultRequestHeads};\n" +
                    "        }\n" +
                    "        config.url = url;\n" +
                    "        config.method = method;\n" +
                    "        return go(config);\n" +
                    "    }\n" +
                    "\n" +
                    "    function get(url, config) {\n" +
                    "        return _go(url, 'GET', config);\n" +
                    "    }\n" +
                    "\n" +
                    "    function post(url, config) {\n" +
                    "        return _go(url, 'POST', config);\n" +
                    "    }\n" +
                    "\n" +
                    "    function put(url, config) {\n" +
                    "        return _go(url, 'PUT', config);\n" +
                    "    }\n" +
                    "\n" +
                    "    function del(url, config) {\n" +
                    "        return _go(url, 'PUT', config);\n" +
                    "    }");

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
